#include "Function.hpp"
#include "EquationSolver.hpp"
#include <iostream>
#include <cmath>

const double Pi = acos(-1.);

class F : public Function {
public:
double l, h, D, beta1;
F(double l, double h, double D, double beta1) : l(l), h(h), D(D), beta1(beta1) {}
    double operator() (double x) const {
    double A = l * sin(beta1);
    double B = l * cos(beta1);
    double C = (h + 0.5 * D) * sin(beta1) - 0.5 * D * tan(beta1);
    double E = (h + 0.5 * D) * cos(beta1) - 0.5 * D;
        return A*sin(x)*cos(x)+B*pow(sin(x), 2)-C*cos(x)-E*sin(x);
    }
};

void solve_f1F() {
    std::cout << "Solving A*sin(x)*cos(x)+B*pow(sin(x), 2)-C*cos(x)-E*sin(x)" << std::endl;
    F f1(89.0,49.0,55.0,11.5 * Pi / 180.0);
    Newton_Method solver_f1(f1, 33.0*Pi/180.0);
    double x = solver_f1.solve();
    std::cout << "alpha is: " << x/Pi*180.0 << std::endl;
}

void solve_f2F() {
    std::cout << "Solving A*sin(x)*cos(x)+B*pow(sin(x), 2)-C*cos(x)-E*sin(x) with the initial guess x_0=33 degrees" << std::endl;
    F f2(89.0,49.0,30.0,11.5 * Pi / 180.0);
    Newton_Method solver_f2(f2, 33.0*Pi/180.0);
    double x = solver_f2.solve();
    std::cout << "alpha is: " << x/Pi*180.0 << std::endl;
}

void solve_f3F() {
    std::cout << "Solving A*sin(x)*cos(x)+B*pow(sin(x), 2)-C*cos(x)-E*sin(x) with x_0=-1000 degrees and x_1=80 degrees" << std::endl;
    F f3(89.0,49.0,55.0,11.5 * Pi / 180.0);
    Secant_Method solver_f31(f3, -1000*Pi/180.0, 33.0*Pi/180.0);
    double x1 = solver_f31.solve();
    std::cout << "alpha is: " << x1/Pi*180.0 << std::endl;
    std::cout << "Solving A*sin(x)*cos(x)+B*pow(sin(x), 2)-C*cos(x)-E*sin(x) with x_0=-1e6 degrees and x_1=80 degrees" << std::endl;
    Secant_Method solver_f32(f3, -1e6*Pi/180.0, 33.0*Pi/180.0);
    double x2 = solver_f32.solve();
    std::cout << "alpha is: " << x2/Pi*180.0 << std::endl;
    std::cout << "Solving A*sin(x)*cos(x)+B*pow(sin(x), 2)-C*cos(x)-E*sin(x) with x_0=-1e10 degrees and x_1=80 degrees" << std::endl;
    Secant_Method solver_f33(f3, -1e12*Pi/180.0, 33.0*Pi/180.0);
    double x3 = solver_f33.solve();
    std::cout << "alpha is: " << x3/Pi*180.0 << std::endl;
}


int main() {
    std::cout << "Question F:" << std::endl;
    solve_f1F();
    solve_f2F();
    solve_f3F();
    return 0;
}